import Header from "./components/Header";
import List from "./components/List";
import Footer from "./components/Footer";
import './App.css'
import { useState } from "react";
import { useEffect } from "react";

/* 
应用组件
*/
export default function App() {

  const [todos, setTodos] = useState(JSON.parse(localStorage.getItem('todos_key')) || [])

  useEffect(() => { // didMount + didUpdate (todos)
    localStorage.setItem('todos_key', JSON.stringify(todos))
  }, [todos])  // 监视了todos


  /* 
  添加todo
  Header传过来什么数据?  title
  */
  const addTodo = (title) => {
    // 根据title创建一个新的todo
    const todo = {id: Date.now(), title, complete: false}
    // 添加到todos
    // 更新todos
    // 问题: 调用setXxx方法更新state时, 不能直接指定原数据, 即使内部数据发生了变化 => 界面不会更新
    // 需要指定一个新的值
    // setTodos(todos) // 传递进去的是一个新的todos吗?  不是, 是同一个, 只是内部多一个todo
    // 需要一个包含todos中所有数据的新数组
    // todos.unshift(todo)
    // console.log('addTodo', todos)
    // setTodos([...todos])
    setTodos([todo, ...todos])

    // todos.unshift(todo)
    // setTodos(todos)  // 组件不会重新调用渲染   内部会进行===的比较, 如果相同不更新
  }

  /* 
  删除指定id对应的todo
  */
  function deleteTodo(id) {
    // 产生一个去除指定id对应的todo的新todos
    const newTodos = todos.filter(todo => todo.id!==id)
    // 更新todos
    setTodos(newTodos)

    // setTodos(todos.filter(todo => todo.id!==id))
  }

  /* 
  反选指定todo: 切换指定todo的complete值
  */
  const toggleTodo = (todo) => {
    // 切换指定todo的complete值
    todo.complete = !todo.complete // 修改的是todos内部的某个todo内部的属性
    // 更新todos
    setTodos([...todos])
  }

  /* 
  清除已完成的todo
  */
  const clearCompleteTodos = () => {
    setTodos(todos.filter(todo => !todo.complete))
  }

  /* 
  全选/全不选
  */
  const selectAll = (isCheck) => {
    // 将每个todo的complete变为isCheck
    todos.forEach(todo => todo.complete = isCheck)
    setTodos([...todos])
  }


  // 第一次执行:  内部创建一个状态数据, 初始值为参数值1, 并定义一个更新数据的函数, 最后返回包含状态数据和更新函数的数组
  // 后面更新执行: 直接返回内存保存的状态数据和更新状态数据的函数
  const [count, setCount] = useState(1)
  console.log('app count', count)

  const updateCount = () => {
    // 更新内部保存的对应状态数据  ==> 调用组件函数更新渲染组件
    setCount(count + 2)
    console.log('count', count)
  }

  // didMount()   初始化调用一次
  useEffect(() => {}, [])
  // didMount() + count didUpdate()
  useEffect(() => {}, [count])
  // didMount() + didUpdate()
  useEffect(() => {})

  // 状态数据定义在哪个组件, 更新数据函数就定义在哪个组件

  return (
    <div className="todo-container">
    <h2 onClick={updateCount}>count: {count}</h2>
    <div className="todo-wrap">
      <Header addTodo={addTodo}/>
      {/* 将todos传递给List */}
      <List todos={todos} deleteTodo={deleteTodo} toggleTodo={toggleTodo}/>
      <Footer todos={todos} clearCompleteTodos={clearCompleteTodos} selectAll={selectAll}/>
    </div>
  </div>
  )
}
